//
// Created by Administrator on 2019/5/29.
//

#include "cn_w_mac_MacAddrOperator.h"
#include "LOG.h"
#include "EPRom.h"

#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include<linux/i2c-dev.h>
#include <linux/i2c.h>
#include <stdio.h>
#include <malloc.h>

int setApiVersion(int apiVersion);

static bool isInit = false;
static int NATIVE_DEVICE_TYPE = 0;

#define DEVICE_TYPE_A64 1
#define DEVICE_TYPE_A20 2

static char *DEVICE_A20_I2C_PATH = "/dev/i2c-2";
static char *DEVICE_A64_I2C_PATH = "/dev/i2c-1";

#define USEFUL_DATE_LENGTH 9    // EPRom 每次读取和写入的长度

static char *i2c_path = 0;

int setApiVersion(int apiVersion) {
    if (apiVersion == 22) {
        NATIVE_DEVICE_TYPE = DEVICE_TYPE_A64;
    } else if (apiVersion == 17) {
        NATIVE_DEVICE_TYPE = DEVICE_TYPE_A20;
    } else {
        NATIVE_DEVICE_TYPE = 0;
    }
    return NATIVE_DEVICE_TYPE;
}

JNIEXPORT jint JNICALL Java_cn_w_mac_MacAddrOperator__1init(JNIEnv *env, jobject thiz) {

    if (isInit)
        return 1;

    char sdkVer[20];
    bzero(sdkVer, sizeof(sdkVer));
    __system_property_get("ro.build.version.sdk", sdkVer);
    LOGE("当前系统API版本:%s\n", sdkVer);
    int androidApiVersion = atoi(sdkVer);
    NATIVE_DEVICE_TYPE = setApiVersion(androidApiVersion);

    int returnValue = 0;

    switch (NATIVE_DEVICE_TYPE) {
        case DEVICE_TYPE_A20:
            LOGE("初始化 A20 部分，EPRom 控制接口");
            i2c_path = DEVICE_A20_I2C_PATH;
            isInit = true;
            break;
        case DEVICE_TYPE_A64:
            LOGE("初始化 A64 部分，EPRom 控制接口");
            i2c_path = DEVICE_A64_I2C_PATH;
            isInit = true;
            break;
        default:
            returnValue = -1;
            isInit = false;
            break;
    }

    return returnValue;

}

JNIEXPORT jint JNICALL Java_cn_w_mac_MacAddrOperator__1close(JNIEnv *env, jobject thiz) {
    return CloseI2c_EPROM();
}

JNIEXPORT jint JNICALL
Java_cn_w_mac_MacAddrOperator__1setMac(JNIEnv *env, jobject thiz, jbyteArray _macAddr,
                                       jint length) {
    int returnValue = -1;

    /**
     * 添加控制为部分
     * 如果长度为 7 最后一位为控制位
     *
     * 控制位部分，为 0x00 或者 0xAA 时，为设备正常，其他为设备异常
     *
     * 是否使能，由系统上层来处理，
     */
    if (length == 6) { // 此部分主要作用用来设置 MAC 地址
        if (InitI2c_EPROM(i2c_path) == 0) {
            unsigned char tempMacAddr[7] = {0x00};
            if (I2cRead_EPROM(0xA0 >> 1, 0, tempMacAddr, 7) == 0) {
                if (tempMacAddr[0] == (unsigned char) 0xAA &&   // 起始位，判断可用性，是否符合标识符规范
                    tempMacAddr[1] == (unsigned char) 0xD0 &&   // MAC 地址校验 第一位
                    tempMacAddr[2] == (unsigned char) 0xC8 &&   // MAC 地址校验 第二位
                    tempMacAddr[3] == (unsigned char) 0x57) {   // MAC 地址校验 第三位
                    CloseI2c_EPROM();
                    return -3; // 存在相关 MAC 地址信息
                }
            } else {
                CloseI2c_EPROM();
                return -2; // EPRom数据读取错误
            }

            jbyte *arr = env->GetByteArrayElements(_macAddr, 0);
            unsigned char reMacAddr[7] = {(unsigned char) 0xAA,
                                          (unsigned char) 0xAA,
                                          (unsigned char) 0xAA,
                                          (unsigned char) 0xAA,
                                          (unsigned char) 0xAA,
                                          (unsigned char) 0xAA,
                                          (unsigned char) 0xAA}; // 定义相关标识符
            memcpy(reMacAddr + 1, arr, length);
            returnValue = I2cWrite_EPROM(0xA0 >> 1, 0, (unsigned char *) reMacAddr, 7);
            env->ReleaseByteArrayElements(_macAddr, arr, JNI_OK);
            CloseI2c_EPROM();
            return 0;
        }
    } else if (length == 7) {
        // 此部分主要作用用来设置 使能状态 ，将直接忽略，第 九位 为 0xAA 说明使能状态可用
        // 此部分，需要写入时，先读取原始内容，如果开头部分，不是符合规则的部分，则原样还原
        if (InitI2c_EPROM(i2c_path) == 0) {
            unsigned char tempMacAddr[USEFUL_DATE_LENGTH] = {0x00};
            if (I2cRead_EPROM(0xA0 >> 1, 0, tempMacAddr, USEFUL_DATE_LENGTH) == 0) {

                if (tempMacAddr[0] == (unsigned char) 0xAA &&   // 起始位，判断可用性，是否符合标识符规范
                    tempMacAddr[1] == (unsigned char) 0xD0 &&   // MAC 地址校验 第一位
                    tempMacAddr[2] == (unsigned char) 0xC8 &&   // MAC 地址校验 第二位
                    tempMacAddr[3] == (unsigned char) 0x57) {   // MAC 地址校验 第三位

                    // 存在 MAC 地址，只设置 使能状态

                    jbyte *arr = env->GetByteArrayElements(_macAddr, 0);
                    tempMacAddr[USEFUL_DATE_LENGTH - 2] = (unsigned char) arr[6];
                    tempMacAddr[USEFUL_DATE_LENGTH - 1] = 0xAA;
                    env->ReleaseByteArrayElements(_macAddr, arr, JNI_OK);
                    returnValue = I2cWrite_EPROM(0xA0 >> 1, 0, (unsigned char *) tempMacAddr,
                                                 USEFUL_DATE_LENGTH);

                } else {
                    // 不存在 MAC 地址，全部设置

                    jbyte *arr = env->GetByteArrayElements(_macAddr, 0);

                    if (arr[0] != 0xAA) { // MAC 地址有效
                        unsigned char reMacAddr[9] = {(unsigned char) 0xAA,
                                                      (unsigned char) 0xAA,
                                                      (unsigned char) 0xAA,
                                                      (unsigned char) 0xAA,
                                                      (unsigned char) 0xAA,
                                                      (unsigned char) 0xAA,
                                                      (unsigned char) 0xAA,
                                                      (unsigned char) 0xAA,
                                                      (unsigned char) 0xAA}; // 定义相关标识符

                        memcpy(reMacAddr + 1, arr, length);
                        returnValue = I2cWrite_EPROM(0xA0 >> 1, 0, (unsigned char *) reMacAddr, 9);
                    } else { // MAC 地址无效

                        tempMacAddr[USEFUL_DATE_LENGTH - 2] = (unsigned char) arr[6];
                        tempMacAddr[USEFUL_DATE_LENGTH - 1] = 0xAA;
                        returnValue = I2cWrite_EPROM(0xA0 >> 1, 0, (unsigned char *) tempMacAddr, 9);

                    }

                    env->ReleaseByteArrayElements(_macAddr, arr, JNI_OK);

                }
                CloseI2c_EPROM();
                return returnValue;
            } else {
                CloseI2c_EPROM();
                return -2; // EPRom数据读取错误
            }
        }
    } else {
        return -1; // 数据长度错误
    }

    return returnValue;
}

JNIEXPORT jint JNICALL
Java_cn_w_mac_MacAddrOperator__1getMac(JNIEnv *env, jobject thiz, jbyteArray _macAddr) {

    int readLength = 0;

    if (InitI2c_EPROM(i2c_path) == 0) {
        jbyte *arr = env->GetByteArrayElements(_macAddr, 0);
        unsigned char tempMacAddr[USEFUL_DATE_LENGTH] = {0x00};
        readLength = I2cRead_EPROM(0xA0 >> 1, 0, tempMacAddr, USEFUL_DATE_LENGTH);
        if (readLength == 0) {
            if (tempMacAddr[0] == (unsigned char) 0xAA) { // MAC 地址有效
                if (tempMacAddr[USEFUL_DATE_LENGTH - 1] == (unsigned char) 0xAA) { // 使能规则符合
                    memcpy(arr, tempMacAddr + 1, 7);
                    readLength = 7;
                } else { // 使能规则无效
                    memcpy(arr, tempMacAddr + 1, 6);
                    readLength = 6;
                }
            } else { // MAC 地址无效
                if (tempMacAddr[USEFUL_DATE_LENGTH - 1] == (unsigned char) 0xAA) { // 使能规则符合
                    memcpy(arr, tempMacAddr + 1, 1);
                    readLength = 1;
                } else { // 使能规则无效
                    readLength = 0;
                }
            }
        } else {
            readLength = 0;
        }
        env->ReleaseByteArrayElements(_macAddr, arr, JNI_OK);
        CloseI2c_EPROM();
    }

    return readLength;
}

